home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
UTILITIE
/
CONVERSI
/
H400.ZIP
/
ZSIM22.ZIP
/
Z80IFACE.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-06-16
|
4KB
|
185 lines
;
; Interface to use the Z80 simulator without cpmbios
;
; (c) 1992 Jürgen Weber
;
; Assemble: tasm /mx Z80IFACE
; (without option /mx there would be the upper case
; a label _EMULATE which is not equal to emulate() )
EXTRN bios88ret:FAR,ctrl_break_req:FAR,interrupt_request:FAR,nmi_irq:FAR
; EXTRN set_read_dist:FAR,set_write_dist:FAR
PUBLIC bios88,prg_exit,port_in,port_out,get_rand
PUBLIC _emulate,_genint,_genhalt,get_rand,port_out,port_in
; PUBLIC _setcfg
DGROUP GROUP _DATA,_BSS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_TEXT segment para public 'Code'
assume cs:_TEXT,es:nothing,ds:nothing
calln_hnd dw 0,0
halt_hnd dw 0,0
; _emulate(unsigned z80seg,
; void far (*calln_handler)(int far *),
; void far (*halt_handler)(void))
spsave dw (?)
_emulate proc far
ARG z80seg:WORD,calln_handler:DWORD,halt_handler:DWORD
mov cs:spsave,sp
push bp
mov bp,sp
lds ax,calln_handler
mov cs:calln_hnd+0,ax
mov ax,ds
mov cs:calln_hnd+2,ax
lds ax,halt_handler
mov cs:halt_hnd+0,ax
mov ax,ds
mov cs:halt_hnd+2,ax
mov ax,[z80seg]
pop bp
mov es,ax
mov ds,ax
mov si,0 ; start at 0
jmp bios88ret
emexit:
mov ax,DGROUP
mov ds,ax
mov sp,cs:spsave
ret
_emulate endp
; call this function to generate an interrupt of the z80
; for example you could hook the timer interrupt to
; call this function
; void genint(void)
_genint proc far
ARG databus:WORD
push bp
mov bp,sp
mov ax,[databus] ; the value in al simulates the value put
pop bp ; on the data bus at z80 irq
call interrupt_request
ret
_genint endp
; call this function to force the z80 to execute HALT (-> prg_exit)
; for example you could hook the ctrl_break interrupt to
; call this function
; void genhalt(void)
_genhalt proc far
call ctrl_break_req
ret
_genhalt endp
; bios88 is called if the bytes ED ED xx are met
; use ED ED xx to execute an operating system call xx (al=xx)
; if xx==0ffh goto emulation exit
bios88 proc far
local rsi,rdx,rcx,rbx,rax:WORD=AUTO_SIZE
cmp al,0ffh
jz emexit ; end emulation
push bp
mov bp,sp
sub sp,AUTO_SIZE
mov di,sp
push ds
push es
mov rax,ax
mov rbx,bx
mov rcx,cx
mov rdx,dx
mov rsi,si
push ss ; int far *regs
push di ; stack grows downwards
mov ax,DGROUP
mov ds,ax
; void far calln_handler(int far *regs);
call dword ptr cs:[calln_hnd]
add sp,4
mov ax,rax
mov bx,rbx
mov cx,rcx
mov dx,rdx
mov si,rsi
pop es
pop ds
mov sp,bp
pop bp
jmp bios88ret
bios88 endp
; prg_exit is called, if a HALT operation is executed
prg_exit proc far
push ds
push es
push si
push ax
push bx
push cx
push dx ; save all registers
mov ax,DGROUP
mov ds,ax
; void far halt_handler(void);
call dword ptr cs:[halt_hnd]
pop dx
pop cx
pop bx
pop ax
pop si
pop es
pop ds
ret
prg_exit endp
port_in proc far
mov al,0ffh
ret
port_in endp
port_out proc far
ret
port_out endp
get_rand proc far
mov al,0
ret
get_rand endp
comment @
; _setcfg(unsigned rdseg,rdoffs,wrseg,wroffs);
; all read accesses are done in segment rdseg by adding rdoffs
; all write accesses are done in segment wrseg by adding wroffs
_setcfg proc far
ARG rdseg:WORD,rdoffs:WORD,wrseg:WORD,wroffs:WORD
push bp
mov bp,sp
mov bx,rdseg
mov ax,rdoffs
call set_read_dist
mov bx,wrseg
mov ax,wroffs
call set_write_dist
pop bp
ret
_setcfg endp
@
_TEXT ends
end